import MarkdownIt from 'markdown-it'
import markdownItHighlight from 'markdown-it-highlightjs'
import React from 'react'
import { ReactElement } from 'react'
import { createRoot } from 'react-dom/client'
import { Input } from '@arco-design/web-react';
import mathjax from 'markdown-it-mathjax3'
const md = new MarkdownIt().use(markdownItHighlight)
function sleep(time: number) {
    return new Promise((resolve) => setTimeout(resolve, time));
}
const lgContent = (url: string): any => new Promise((resolve: (c0: any) => void, reject: (c0: any) => void) => {
    void $.get(`${url + (url.includes('?') ? '&' : '?')}_contentOnly=1`, (data: { code: number }) => {
        if (data.code !== 200) reject(new Error(`Requesting failure code: ${data.code}.`))
        resolve(data)
    })
})

const getUid = (name: string): any => new Promise((resolve: (c0: any) => void, reject: (c0: any) => void) => {
    void $.get(`https://www.luogu.com.cn/api/user/search?keyword=${name}`, (data, status: string) => {
        if (status !== 'success') reject(new Error(`Requesting failure code: ${status}`))
        resolve(data)
    })
})
function callback(res: number, blogid: number, bloglink: string) {
    res *= 100.0;
    var ls_res = Number((document.getElementById(`Diff${blogid}`) as HTMLElement).innerText.split(`%`)[0]);
    if (Number.isNaN(ls_res) || ls_res == 0) {
        (document.getElementById(`Diff${blogid}`) as HTMLElement).innerText = `${res.toFixed(2)}%`;
        (document.getElementById(`Diff${blogid}`) as HTMLLinkElement).href = bloglink;
        (document.getElementById(`Diff${blogid}`) as HTMLLinkElement).setAttribute(`style`, `color: ${res >= 45 ? (res >= 70 ? '#fb6340' : '#e67e22') : '#2dce89'}; font-size: 2rem;font-width:700 `);
    }
    else {
        if (res > ls_res) {
            (document.getElementById(`Diff${blogid}`) as HTMLElement).innerText = `${res.toFixed(2)}%`;
            (document.getElementById(`Diff${blogid}`) as HTMLLinkElement).href = bloglink;
            (document.getElementById(`Diff${blogid}`) as HTMLLinkElement).setAttribute(`style`, `color: ${res >= 75 ? (res >= 60 ? '#fb6340' : '#e67e22') : '#2dce89'}; font-size: 2rem;font-width:700 `);
        }
    }
}
// 创建线程函数
function createWorker(task: Function, s1: string, s2: string, blogid: number, bloglink: string) {
    var blob = new Blob([`(` + task.toString() + `)(\`${s1.replace(/\\/g, `\\\\`).replace(/`/g, `\\\``).replace(/\$\s*\{/g, `\${`)}\`,\`${s2.replace(/\\/g, `\\\\`).replace(/`/g, `\\\``).replace(/\$\s*\{/g, `\${`)}\`)`]);
    var url = window.URL.createObjectURL(blob);
    var worker = new Worker(url);
    worker.onmessage = (workerData) => {
        callback(Number(workerData.data.res), blogid, bloglink)
    }
    return worker;
}
/**
 * 查重率统计
 * @param {string} s1 已通过题解内容
 * @param {string} s2 当前审核题解内容
 */
function getSimPoint(s1: string, s2: string) {
    s1 = s1.replace(/int|for|if|，|。|：|\+|-|\\|#include|#define|void|signed|string|vector|pair/g, "");
    s2 = s2.replace(/int|for|if|，|。|：|\+|-|\\|#include|#define|void|signed|string|vector|pair/g, "");
    var l1 = s1.length;
    var l2 = s2.length;
    var dp: number[][];
    dp = [];
    for (var i = 0; i <= l1; i++) {
        dp.push([]);
        for (var j = 0; j <= l2; j++) {
            if (i == 0) {
                dp[i][j] = j;
            }
            else if (j == 0) {
                dp[i][j] = 0;
            }
            else if (s1[i] == s2[j]) {
                dp[i][j] = dp[i - 1][j - 1];
            }
            else {
                dp[i][j] = Math.min(
                    // 改变一个字符
                    dp[i - 1][j - 1] + 1,
                    // 增加一个字符
                    dp[i][j - 1] + 1,
                    // 删除一个字符
                    dp[i - 1][j]);
            }
        }
    }
    const res = 1.0 - ((dp[l1][l2] * 1.0) / l2);
    postMessage({ "res": res.toString() });
    self.close();
}

const getAcceptArticles = async (articleList: IArticle[]): Promise<void> => {
    var Data: string = ``;
    var sumLen = 0;

    for (var j = 0; j < articleList.length; j++) {
        var art = articleList[j];
        await $.get(`https://www.luogu.com.cn/webadmin/blog/article?status=%5B%5D&solution=%5B2%5D&pid=${art.pid}`, (data) => {
            Data = data;
        })
        var k = new DOMParser()
        var t = k.parseFromString(Data, `text/html`);
        var pp = t.getElementsByClassName(`am-btn am-btn-default am-btn-xs`);
        for (var i = 0; i < pp.length; i++) {

            var e = pp[i];
            (function a(eid, tim, txt, idx) {
                setTimeout(() => {
                    $.get((eid as HTMLLinkElement).href, (dta) => {
                        var DM = new DOMParser();
                        var kkk = DM.parseFromString(dta, `text/html`);
                        var Text = kkk.getElementsByName(`content`)[0].innerText;
                        createWorker(getSimPoint, Text, txt, idx, (eid as HTMLLinkElement).href);
                    })
                }, tim)
            }
            )(e, 280 * (sumLen) + i * 255, art.blogContent, art.blogid);
        }
        sumLen += pp.length;
    }
    return;
}
const pinkrabbitFilter = (str: string): string => {
    const bread = (word: string): string => `<span class="detected_misformat">${word}</span>`
    str = str.replace(/(?<=[^$])[\w$][^\x00-\x7F,，.。;；:：!！?？"“”（）、]/g, bread)
    str = str.replace(/[^\x00-\x7F,，.。;；:：!！?？"“”（）、][\w$](?=[^$])/g, bread)
    str = str.replace(/(?<=\$[\x00-\x7f]*[^\\bB]|\$)log(?=[\x00-\x7f]*\$)/g, bread)
    str = str.replace(/(?<=\$[\x00-\x7f]*[^\\]|\$)(min|max|gcd)(?=[\x00-\x7f]*\$)/g, bread)
    str = str.replace(/(?<=\$[\x00-\x7f]*)(<=|>=|==|bfs|dfs|\*)(?=[\x00-\x7f]*\$)/g, bread)
    // /* ∑≠⊆∈× */
    return str
}

interface IArticleWithoutContent {
    pid: string
    color: string // difficulty
    articleBody: HTMLElement
    head: HTMLElement
    blogid: number
    blogContent: string
    present: number
    persentAccepted: number
    passed: boolean
    time: number
    title: string
    blogtitle: string
    authoruid: number
    authorname: string
    authorcolor: string
    authorbadge: string
    authorccf: number
    clzMode: boolean
}

interface IArticle extends IArticleWithoutContent {
    HTMLNoKaTeX: string
    ORIHTML: string
}
export interface IHistory {
    articles: IArticleWithoutContent[]
    accept: number
    decline: number
}

async function initArticle(args: HTMLElement): Promise<IArticle> {
    const s: IArticle = {
        pid: '',
        color: '',
        articleBody: args,
        blogid: -1,
        head: args?.querySelector('h1.am-article-title') ?? document.body,
        blogContent: '',
        present: 0,
        persentAccepted: 0,
        passed: false,
        title: '',
        blogtitle: '',
        authoruid: -1,
        authorname: '',
        authorcolor: '',
        authorbadge: '',
        authorccf: 0,
        HTMLNoKaTeX: '',
        clzMode: false,
        ORIHTML: '',
        time: 0
    }
    s.blogid = (s.articleBody.dataset.blogid != null) ? parseInt(s.articleBody.dataset.blogid) : 0
    s.blogtitle = s.head.firstElementChild?.innerHTML ?? ''
    const tmp = s.head.innerText.match(/.*By (.*)/)
    if (tmp !== null && tmp.length > 1) s.authorname = tmp[1]
    // s.pid = s.head.nextElementSibling?.getAttribute(`href`)?.split('/').at(-1) ?? '';
    s.pid = s.head?.nextElementSibling?.getAttribute(`href`)?.split(`/`)?.at(-1) ?? '';
    await sleep(100);
    const problem = await lgContent(`/problem/${s.pid}`)
    s.authorname = s.authorname.trim().split(' ')[0]
    await sleep(100);
    const author = (await getUid(s.authorname)).users[0]
    s.authoruid = +author.uid
    if (author.badge !== null) s.authorbadge = author.badge
    s.authorccf = +author.ccfLevel
    s.authorcolor = author.color
    s.color = problem.currentData.problem.difficulty
    s.title = problem.currentTitle
    return s
}

async function getClzHTML(s: IArticle) {
    s.blogContent = $(await GetBlogContent(s.blogid)).find('textarea').first().text()
    const SrcSplit = s.blogContent.split(/\\/)
    let mdSrcCode = SrcSplit[0]
    for (let i = 1; i < SrcSplit.length; i++) mdSrcCode = mdSrcCode + '\\\\' + SrcSplit[i]
    s.present = Number(s.articleBody?.querySelector('.am-article-meta')?.firstElementChild?.innerHTML ?? '-1')
    if (navigator.userAgent.match(`Firefox`) !== null) {
        s.HTMLNoKaTeX = md.render(mdSrcCode);
        return s;
    }
    s.HTMLNoKaTeX = pinkrabbitFilter(md.render(mdSrcCode))

}
async function getProbability(sourceCode: any): Promise<number> {
    try {
        // const url = `http://cn.gandyli.xyz:5201/run/predict`;
        const url = 'https://www.modelscope.cn/api/v1/studio/simpleai/chatgpt-detector-single/gradio/run/predict/'
        AbortSignal.timeout ??= function timeout(ms) {
            const ctrl = new AbortController()
            setTimeout(() => { ctrl.abort() }, ms)
            return ctrl.signal
        }
        const res = await fetch(url, {
            body: JSON.stringify({
                data: [sourceCode],
                dataType: ['textbox'],
                fn_index: 1,
                session_hash: 'aamtnn1x42r'
            }),
            method: 'POST',
            signal: AbortSignal.timeout(1500)
        }).then(async x => await x.json())
        const human = res.data[0] === '人类'
        let probability = Number(res.data[1])
        if (human) {
            probability = 1 - probability
        }
        return probability
    } catch (err) {
        console.error(err)
        return -1
    }
}

async function GetBlogContent(blogid: number): Promise<any> {
    let E: any
    // for (let i = 0; i < 10; i++) {
    const ans = await $.get(`/webadmin/blog/editArticle/${blogid}`, (data, status) => {
        E = status
        if (status !== 'success') return 'Error'
        return data
    })
    if (ans !== 'Error') { return ans }
    // }
    Error(E)
}


/**
 * jsx 转 HTML
 * @param {ReactElement<any, string | React.JSXElementConstructor<any>>} jsxelem 
 * @returns {HTMLElement}
 */
async function jsxToDom(jsxelem: ReactElement<any, string | React.JSXElementConstructor<any>>): Promise<HTMLElement> {
    let jsxRenderDiv = document.createElement(`div`);
    let jsxRender = createRoot(jsxRenderDiv);
    jsxRender.render(jsxelem);
    function waitForRender() {
        return new Promise<void>((resolve) => {
            if (jsxRenderDiv.innerHTML !== ``) {
                resolve()
            }
            else {
                setTimeout(() => {
                    waitForRender().then(resolve)
                }, 200);
            }
        })
    }
    await waitForRender();
    return jsxRenderDiv;

}

/**
  * @description get svg by ccfLevel
  * @param {number} ccfLevel 
  * @returns {React.JSX.Element} the svg of User
  */
function getUserSvg(ccfLevel: number): React.JSX.Element {
    if (ccfLevel === 0) {
        return <></>;
    }
    const green = '#52c41a';
    const blue = '#3498db';
    const gold = '#ffc116';
    const color = (ccfLevel >= 3 && ccfLevel <= 5) ? green : ((ccfLevel >= 6 && ccfLevel <= 7) ? blue : gold)
    return <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill={color} style={{ marginBottom: "-3px" }}>
        <path d="M16 8C16 6.84375 15.25 5.84375 14.1875 5.4375C14.6562 4.4375 14.4688 3.1875 13.6562 2.34375C12.8125 1.53125 11.5625 1.34375 10.5625 1.8125C10.1562 0.75 9.15625 0 8 0C6.8125 0 5.8125 0.75 5.40625 1.8125C4.40625 1.34375 3.15625 1.53125 2.34375 2.34375C1.5 3.1875 1.3125 4.4375 1.78125 5.4375C0.71875 5.84375 0 6.84375 0 8C0 9.1875 0.71875 10.1875 1.78125 10.5938C1.3125 11.5938 1.5 12.8438 2.34375 13.6562C3.15625 14.5 4.40625 14.6875 5.40625 14.2188C5.8125 15.2812 6.8125 16 8 16C9.15625 16 10.1562 15.2812 10.5625 14.2188C11.5938 14.6875 12.8125 14.5 13.6562 13.6562C14.4688 12.8438 14.6562 11.5938 14.1875 10.5938C15.25 10.1875 16 9.1875 16 8ZM11.4688 6.625L7.375 10.6875C7.21875 10.8438 7 10.8125 6.875 10.6875L4.5 8.3125C4.375 8.1875 4.375 7.96875 4.5 7.8125L5.3125 7C5.46875 6.875 5.6875 6.875 5.8125 7.03125L7.125 8.34375L10.1562 5.34375C10.3125 5.1875 10.5312 5.1875 10.6562 5.34375L11.4688 6.15625C11.5938 6.28125 11.5938 6.5 11.4688 6.625Z"></path>
    </svg>;
}


//         undefine red ora ye gr  bu pur blk
const MaxCount = [10, 5, 7, 7, 10, 12, 17, 20]

const reasons = {
    fatalReasons: [
        { display: '解法重复', full: '与题解区解法大量重复' },
        { display: '文章雷同', full: '文章内容与他人文章大量雷同，涉嫌抄袭' },
        { display: '违规内容', full: '文章含有违规内容' }
    ],
    normalReasons: [
        {
            title: '基本规范',
            list: [
                { display: '缺公式', full: '数学公式（运算式、运算符、数学推导、参与运算的常数、作为变量的字母等）应使用 LaTeX' },
                { display: '多公式', full: '非数学公式（一般英文单词、题目名、算法名、人名等）不应使用 LaTeX' },
                { display: '缺空格', full: '【中文】与【英文、数字或公式】之间应以半角空格隔开' },
                { display: '多空格', full: '【中文标点符号】与【英文、数字、公式或汉字】之间不应添加多余空格' },
                { display: '公式内标点', full: '数学公式内应使用英文半角标点' },
                { display: '公式外标点', full: '数学公式外应使用中文全角标点' },
                { display: '句末句号', full: '句子末尾应添加句号，且全文使用的句号应一致' }
            ]
        },
        {
            title: '题解内容',
            list: [
                { display: '无意义', full: '不应出现大量无关内容，应只包含题目相关内容，包括但不限于题意简述、题目分析等' },
                { display: '缺分析', full: '应当补充对解法进一步的说明，不应只体现在代码的注释中' },
                { display: '缺证明', full: '应当补充对重要结论的证明' },
                { display: '不正确', full: '解法存在事实性错误' },
                { display: '复杂度有误', full: '解法的时间复杂度分析不当或使用的记号不当' },
                { display: '复杂度不当', full: '解法的时间复杂度无法在合理范围内通过本题' },
                { display: 'ChatGPT', full: '解法应当由自己完成，表述应当合理且通顺' }
            ]
        },
        {
            title: '排版',
            list: [
                { display: '滥用标题行', full: '不应滥用标题行表示强调与无意义内容' },
                { display: '滥用粗体', full: '不应大段或过多使用粗体' },
                { display: '滥用代码块', full: '非字符串或代码内容不应滥用代码块' },
                { display: '列表使用', full: '有序列表或无序列表使用不当或用法有误' },
                { display: '行内代码块', full: '应使用行内代码块表示字符串或代码' },
                { display: '行间代码块', full: '应使用行间代码块引用代码或样例' },
                { display: '列表致缩进', full: '列表后接标题行或行间代码时，中间应留有空行' },
                { display: '图片与链接', full: '应正确使用 markdown 语法引用图片或链接' }
            ]
        },
        {
            title: '数学公式',
            list: [
                { display: '同一公式', full: '同一个数学公式应写在一个 LaTeX 环境内，不应分开写，例如 `$a + b = c$` 不应写为 `$a$ + $b$ = $c$` 或 `$a$ $+$ $b$ $=$ $c$`' },
                { display: '公式文本', full: '数学公式中的文本应使用 \\text，字符串应使用 \\texttt' },
                { display: '行间公式', full: '公式独立成行时应使用行间公式' },
                { display: '数学语言', full: '数学公式中应使用数学语言而非代码语言，如赋值语句、判定语句、整除、取模、位运算等' },
                { display: '上下标', full: '上下标应使用 $a _ {b} ^ {c}$（`$a _ {b} ^ {c}$`）进行表示' },
                { display: '科学记数法', full: '大数字应使用科学计数法表示，如 $5 \\times 10 ^ 9$' },
                { display: '时间复杂度', full: '时间复杂度的大 $O$ 记号中不应带有常数，如有值域、字符集大小等常量，应使用字母进行表示' },
                { display: '运算符', full: '应正确使用运算符，如 $+, -, \\pm, \\times, \\cdot, \\div, \\le, \\ge, \\mid$（`$+, -, \\pm, \\times, \\cdot, \\div, \\le, \\ge, \\mid$`）' },
                { display: '函数名', full: '特定的、约定俗成的函数名称应该使用正体，如 $\\gcd, \\max, \\min, \\log, \\det$（`$\\gcd, \\max, \\min, \\log, \\det$`）。特别地，对于一些未定义的函数，应使用 `\\operatorname`，如 $\\operatorname{lcm}$（`\\operatorname{lcm}`）' },
                { display: '大型运算符', full: '应正确使用大型运算符，如 $\\sum, \\prod, \\bigcup, \\bigcap$（`$\\sum, \\prod, \\bigcup, \\bigcap$`）' },
                { display: '取模', full: '应正确使用取模符号：取模运算应使用 `\\bmod`，如 $a \\bmod b = c$（`$a \\bmod b = c$`）；同余符号应使用 `\\equiv` 与 `\\pmod`，如 $a \\equiv c \\pmod b$（`$a \\equiv c \\pmod b$`）' },
                { display: '数学结构', full: '应正确使用数学结构符号，如 $\\frac{a}{b}, \\sqrt{a}, \\overline{a}, \\{a\\}$（`$\\frac{a}{b}, \\sqrt{a}, \\overline{a}, \\{a\\}$`）' },
                { display: '特殊符号', full: '应正确使用特殊符号，如 $\\gets, \\to, \\Leftarrow, \\Rightarrow, \\Leftrightarrow, \\sim$（`$\\gets, \\to, \\Leftarrow, \\Rightarrow, \\Leftrightarrow, \\sim$`）' },
                { display: '省略号', full: '省略号应使用 $\\dots, \\cdots, \\ldots$（`$\\dots, \\cdots, \\ldots$`），特别地，矩阵中其它方向的省略号应使用 $\\vdots, \\ddots$（`$\\vdots, \\ddots$`）' },
                { display: '大型环境', full: '连等式应使用 `\\aligned` 环境，分段函数应使用 `\\cases` 环境，矩阵应使用 `\\bmatrix` 环境' }
            ]
        },
        {
            title: '图片与代码',
            list: [
                { display: '图片不适', full: '题解中引用的图片应简洁、清晰、美观，图片中的文本应满足格式要求' },
                { display: '图片链接', full: '不应引用带有链接的图片' },
                { display: '代码过长', full: '过长的代码或代码片段不应放在题解中，如有必要，请使用洛谷云剪贴板' },
                { display: '代码可读性', full: '代码应具有一定的可读性，可以适当添加有意义的注释进行阐释' },
                { display: '代码防抄袭', full: '不应在代码中加入防抄袭内容' }
            ]
        },
        {
            title: '提交与审核',
            list: [
                { display: '规范链接', full: '提交审核时应确保题解符合题解规范：https://www.luogu.com.cn/discuss/174934' },
                { display: '拒绝提醒', full: '请按照规范与反馈对题解进行修改，多次拒绝后仍未实质性修改将会封禁博客权限' }
            ]
        }
    ]
}

export const colorStyle = {
    Gray: { fontWeight: '700', color: 'rgb(191,191,191)' },
    Blue: { fontWeight: '700', color: 'rgb(52, 152, 219)' },
    Green: { fontWeight: '700', color: ' rgb(82, 196, 26)' },
    Orange: { fontWeight: '700', color: 'rgb(243, 156, 17)' },
    Red: { fontWeight: '700', color: 'rgb(254, 76, 97)' },
    Purple: { fontWeight: '700', color: 'rgb(157, 61, 207)' },
    Cheater: { fontWeight: '700', color: 'rgb(173, 139, 0)' }
}
//时间戳转化成时间格式
function timeFormat(timestamp: number) {
    //timestamp是整数，否则要parseInt转换,不会出现少个0的情况
    //如果timestamp是10位数的需要 timestamp* 1000
    var time = new Date(timestamp);
    var year = time.getFullYear();
    var month = time.getMonth() + 1;
    var date = time.getDate();
    var hours = time.getHours();
    var minutes = time.getMinutes();
    var seconds = time.getSeconds();
    return year + '-' + add0(month) + '-' + add0(date) + ' ' + add0(hours) + ':' + add0(minutes) + ':' + add0(seconds);
}
function add0(m: number): string {
    return m < 10 ? '0' + m.toString() : m.toString();
};
export const HistoryCom = [{
    title: "状态",
    dataindex: 'passed',
    render: (_col: number, record: IArticleWithoutContent, _index: number) => (
        <svg width="16px" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" className="icon svg-inline--fa fa-check fa-w-16" style={(!record.passed) ? { color: 'rgb(231, 76, 60)' } : { color: 'rgb(82, 196, 26)' }} >
            {
                ((!record.passed)
                    ?
                    <path fill="currentColor" d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z" > </path>
                    :
                    <path fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" > </path>)
            }
        </svg >
    ),
    sortable: {
        sortDirections: ['ascend', 'descend']
    },
    filterable: true
},
{
    title: "题号",
    dataindex: 'pid',
    render: (_col: number, record: IArticleWithoutContent, _index: number) => (
        <a href={`/problem/${record.pid}`} className="exadmin-difficulty-color color-exadmin-difficulty-color color-${History.articles[j].color}" style={{ fontWeight: 'normal' }}>
            <span style={{ fontWeight: 'bold' }}> {record.pid}</span>
        </a>
    ),
    filterDropdown: ({ filterKeys, setFilterKeys, confirm }: { filterKeys: string[] | undefined, setFilterKeys: Function, confirm: Function }) => {
        return (
            <div className='arco-table-custom-filter'>
                <Input.Search
                    searchButton
                    placeholder='请输入题目编号'
                    value={filterKeys![0] ?? ''}
                    onChange={(value) => {
                        setFilterKeys(value ? [value] : []);
                    }}
                    onSearch={() => {
                        confirm();
                    }}
                />
            </div>
        );
    },
    onFilter: (value: string, row: IArticleWithoutContent) => {
        return (value ? row.pid.indexOf(value) !== -1 : true)
    }
},
{
    title: "题目名",
    dataindex: 'title',
    render: (_col: number, record: IArticleWithoutContent, _index: number) => (
        <a href={`/problem/${record.pid}`} className="exadmin-difficulty-color color-exadmin-difficulty-color color-${History.articles[j].color}" style={{ fontWeight: 'normal' }}>
            {record.title}
        </a>
    )
},
{
    title: "题解标题",
    dataindex: 'title',
    render: (_col: number, record: IArticleWithoutContent, _index: number) => (
        <a href={`/webadmin/blog/editArticle/${record.blogid}`}>
            {record.blogtitle}
        </a>
    )
},
{
    title: "作者",
    dataindex: 'authorname',
    render: (_col: number, record: IArticleWithoutContent, _index: number) => (
        <>
            <a href={`/user/${record.authoruid}`}>
                <span style={colorStyle[record.authorcolor as keyof typeof colorStyle]}>{record.authorname}</span>
                &nbsp;&nbsp;
                {getUserSvg(record.authorccf)}
                {record.authorcolor === `Purple` ? <>&nbsp;&nbsp;<span className="am-badge am-radius lg-bg-purple">{record.authorbadge !== '' ? record.authorbadge : '管理员'}</span></> : <></>}
                {record.authorcolor === `Cheater` ? <>&nbsp;&nbsp;<span className="am-badge am-radius lg-bg-brown">作弊者</span></> : <></>}

            </a>
        </>
    ),
    filterDropdown: ({ filterKeys, setFilterKeys, confirm }: { filterKeys: string[] | undefined, setFilterKeys: Function, confirm: Function }) => {
        return (
            <div className='arco-table-custom-filter'>
                <Input.Search
                    searchButton
                    placeholder='请输入作者名称（字串）'
                    value={filterKeys![0] ?? ''}
                    onChange={(value) => {
                        setFilterKeys(value ? [value] : []);
                    }}
                    onSearch={() => {
                        confirm();
                    }}
                />
            </div>
        );
    },
    onFilter: (value: string, row: IArticleWithoutContent) => {
        return (value ? row.authorname.indexOf(value) !== -1 : true)
    },

},
{
    title: "审核时间",
    dataindex: 'time',
    render: (_col: number, record: IArticleWithoutContent, _index: number) => (
        <span>
            {timeFormat(record.time)}
        </span>
    ),
    sorter: (a: IArticleWithoutContent, b: IArticleWithoutContent) => a.time - b.time
}
]

export { initArticle, getClzHTML, getProbability, lgContent, MaxCount, getAcceptArticles, reasons, jsxToDom, sleep, type IArticle }
